package com.engine4cloud.tdf.supervision.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.engine4cloud.tdf.common.core.constant.enums.CorAuditActionStatusEnum;
import com.engine4cloud.tdf.common.core.exception.ValidateCodeException;
import com.engine4cloud.tdf.common.security.service.TdfUser;
import com.engine4cloud.tdf.common.security.util.SecurityUtils;
import com.engine4cloud.tdf.supervision.component.CallBackComponent;
import com.engine4cloud.tdf.supervision.convert.JzdxAuditResultConvert;
import com.engine4cloud.tdf.supervision.dto.JzdxAuditDTO;
import com.engine4cloud.tdf.supervision.dto.create.JzdxAuditAcceptCreateDTO;
import com.engine4cloud.tdf.supervision.dto.create.JzdxAuditAssignCreateDTO;
import com.engine4cloud.tdf.supervision.dto.create.JzdxAuditCreateDTO;
import com.engine4cloud.tdf.supervision.dto.result.JzdxAuditResultDTO;
import com.engine4cloud.tdf.supervision.dto.result.JzdxResultDTO;
import com.engine4cloud.tdf.supervision.dto.update.JzdxPreActionUpdateDTO;
import com.engine4cloud.tdf.supervision.dto.update.JzdxUpdateStatusDTO;
import com.engine4cloud.tdf.supervision.entity.JzdxAuditResultEntity;
import com.engine4cloud.tdf.supervision.mapper.JzdxAuditResultMapper;
import com.engine4cloud.tdf.supervision.service.JzdxAuditResultService;
import com.engine4cloud.tdf.supervision.service.JzdxElectronicFenceService;
import com.engine4cloud.tdf.supervision.service.JzdxReportReceiveCaseService;
import com.engine4cloud.tdf.supervision.service.JzdxService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

/**
 * 矫正对象审核-结果表
 *
 * @author wenjie
 * @date 2024-03-18 15:23:15
 */
@Service
public class JzdxAuditResultServiceImpl extends ServiceImpl<JzdxAuditResultMapper, JzdxAuditResultEntity> implements JzdxAuditResultService {
    @Lazy
    @Resource
    private JzdxService jzdxService;
    @Lazy
    @Resource
    private JzdxReportReceiveCaseService reportReceiveCaseService;
    @Lazy
    @Resource
    private JzdxElectronicFenceService electronicFenceService;

    @Resource
    private CallBackComponent callBackComponent;

    @Override
    public Boolean audit(JzdxAuditCreateDTO dto, JzdxAuditDTO audit) {
        jzdxService.changeAction(new JzdxPreActionUpdateDTO(dto.getRybh(), audit.getStatus()));
        return super.save(JzdxAuditResultConvert.INSTANCE.create(dto, audit, SecurityUtils.getUser()));
    }

    @Override
    public Boolean create(JzdxAuditCreateDTO dto, JzdxAuditDTO audit) {
        return super.save(JzdxAuditResultConvert.INSTANCE.create(dto, audit, SecurityUtils.getUser()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean assign(JzdxAuditAssignCreateDTO dto) {
        JzdxResultDTO dx = Optional.ofNullable(jzdxService.getByCode(dto.getRybh()))
                .orElseThrow(() -> new ValidateCodeException("矫正对象不存在"));

        Integer absence = jzdxService.absence(dto.getRybh());
        if (absence > 0) {
            throw new ValidateCodeException("矫正对象信息不完整，请补充基本信息和刑罚信息后再指派");
        }

        //设置状态
        this.audit(dto, new JzdxAuditDTO(SecurityUtils.getUser().getDeptId(), CorAuditActionStatusEnum.COUNTRY_ASSIGN));
        //设置接收情况
        reportReceiveCaseService.saveOrUpdateByCode(dto, dx.getTenantId());
        //转换部门
        return jzdxService.changeDepart(JzdxAuditResultConvert.INSTANCE.update(dto.getRybh(), dto.getJsbm()), CorAuditActionStatusEnum.COUNTRY_ASSIGN);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean accept(JzdxAuditAcceptCreateDTO dto) {
        JzdxResultDTO dx = Optional.ofNullable(jzdxService.getByCode(dto.getRybh()))
                .orElseThrow(() -> new ValidateCodeException("矫正对象不存在"));

        JzdxAuditResultDTO audit = Optional.ofNullable(this.getLatest(dto.getRybh(), CorAuditActionStatusEnum.COUNTRY_ASSIGN))
                .orElseThrow(() -> new ValidateCodeException("前置流程：" + CorAuditActionStatusEnum.COUNTRY_ASSIGN.getDesc() + "未找到，请确认后再操作"));

        //设置矫正状态
        this.audit(dto, new JzdxAuditDTO(audit.getPreDeptId(), CorAuditActionStatusEnum.VILLAGE_ACCEPT));
        //设置报到情况
        reportReceiveCaseService.updateByCode(dto);
        //设置矫正对象所属四级部门
        jzdxService.setDepart(dx);

        //事务提交之后，设置默认行政区划电子围栏
        if (StringUtils.isNotEmpty(dx.getGdjzdszxq())) {
            callBackComponent.execute(() -> electronicFenceService.createDefault(dx.getRybh()));
        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setStatus(JzdxUpdateStatusDTO dto) {
        JzdxResultDTO result = Optional.ofNullable(jzdxService.getByCode(dto.getCode()))
                .orElseThrow(() -> new ValidateCodeException("数据不存在"));

        this.audit(new JzdxAuditCreateDTO(dto.getCode()), new JzdxAuditDTO(dto.getDeptId(), dto.getStatus()));
    }

    @Override
    public Boolean refuse(JzdxAuditCreateDTO dto) {
        TdfUser user = SecurityUtils.getUser();
        JzdxAuditResultDTO audit = Optional.ofNullable(this.getLatest(dto.getRybh(), CorAuditActionStatusEnum.COUNTRY_ASSIGN))
                .orElseThrow(() -> new ValidateCodeException("前置流程：" + CorAuditActionStatusEnum.COUNTRY_ASSIGN.getDesc() + "未找到，请确认后再操作"));
        //设置状态
        this.audit(dto, new JzdxAuditDTO(user.getDeptId(), CorAuditActionStatusEnum.VILLAGE_REFUSE));
        //转换部门
        return jzdxService.changeDepart(JzdxAuditResultConvert.INSTANCE.update(dto.getRybh(), audit.getPreDeptId()), CorAuditActionStatusEnum.VILLAGE_REFUSE);
    }

    @Override
    public JzdxAuditResultDTO getLatest(String code, CorAuditActionStatusEnum status) {
        return this.baseMapper.findLatest(code, status.getType());
    }
}